package com.shizhefei.view.largeimage.remote;

import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.LinkedList;

public class EventSender {
    private EventSender() {
        Log.d("wangweili:", "create instance");
        running = false;
        Handler h = new Handler(Looper.getMainLooper());
    }

    public static EventSender getSender() {
        return sender;
    }

    static EventSender sender = null;

    public static EventSender getInstance() {
        if (sender == null) {
            sender = new EventSender();
        }
        return sender;
    }
    Socket socket = null;
    //OutputStream os = null;
    //InputStream is = null;

    public boolean isRunning() {
        return running;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    volatile boolean running = false;
    boolean wantstop = false;
    static Object object = new Object();
    LinkedList<String> event_list = new LinkedList<>();
    private final static int CAPACITY = 50;
    public boolean insert(String s) {
        if (!running)
            return false;
        synchronized (object) {
            if (event_list.size() >= CAPACITY)
                return false;
            event_list.push(s);
            object.notify();
        }
        return true;
    }

    public boolean connect_remote() {
        try {
            socket = new Socket("192.168.3.76", 8899);
        } catch (IOException e) {
            //throw new RuntimeException(e);
            e.printStackTrace();
        }
        if (socket == null) {
            Log.d("wangweili:", "socket is null !!!");
            return false;
        }
        Log.d("wangweili:", "socket :" + socket.toString());
        return true;
    }

    public boolean connect_remote(String ip) {
        try {
            socket = new Socket(ip, 8899);
        } catch (IOException e) {
            //throw new RuntimeException(e);
            e.printStackTrace();
        }
        if (socket == null) {
            Log.d("wangweili:", "socket is null !!!");
            return false;
        }
        Log.d("wangweili:", "socket :" + socket.toString());
        return true;
    }

    public void stop_sender() {
        Log.d("wangweili:", "command 502 stop receiver and sender !! ");
        wantstop = true;
        JSONObject jroot = new JSONObject();
        try {
            jroot.put("command", 502);
        } catch (JSONException e) {
            // throw new RuntimeException(e);
            e.printStackTrace();
        }
        insert(jroot.toString());
    }

    public void start_sender(String ip) {
        wantstop = false;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Log.d("wangweili:", "will start sender ");
                running = true;
                if(!connect_remote(ip)) {
                    running = false;
                    return;
                }
                while (running) {
                    String s = null;
                    synchronized (object) {
                        if (event_list.isEmpty()) {
                            try {
                                Log.d("wangweili:", "sender wait !!!");
                                object.wait();
                                Log.d("wangweili:", "sender notified !!!");
                            } catch (InterruptedException e) {
                                //throw new RuntimeException(e);
                                e.printStackTrace();
                                running = false;
                            }
                        }
                        s = event_list.removeFirst();
                    }
                    OutputStream os = null;
                    InputStream is = null;
                    try {
                        os = socket.getOutputStream();
                        is = socket.getInputStream();
                    } catch (IOException e) {
                        //throw new RuntimeException(e);
                        e.printStackTrace();
                        running = false;
                        break;
                    }
                    StringBuilder sb = new StringBuilder();
                    sb.append(s).setLength(256);
                    Log.d("wangweili:", "will send " + sb.toString().trim());
                    try {
                        os.write(sb.toString().getBytes());
                        byte[] buffer = new byte[64];
                        int cnt_read = 0;
                        int len_read = 64;
                        Log.d("wangweili:", "will read ");
                        while(cnt_read != 64) {
                            int r = is.read(buffer, cnt_read, len_read);
                            Log.d("wangweili:", " read " + r + "bytes");
                            cnt_read += r;
                            len_read -= r;
                        }
                        Log.d("wangweili:", "will over !!!");
                        String response = new String(buffer, 0, 64, Charset.defaultCharset());
                        Log.d("wangweili:", "response = " + response.trim());
                    } catch (IOException e) {
                        e.printStackTrace();
                        running = false;
                    }
                    if (wantstop == true) {
                        running = false;
                        event_list.clear();
                        try {
                            Log.d("wangweili:", "close socket  !!!");
                            if (socket != null)
                                socket.close();
                        } catch (IOException e) {
                            //throw new RuntimeException(e);
                            e.printStackTrace();
                        }
                        Log.d("wangweili:", "sender exit !!!");
                    }
                }
            }
        };
        new Thread(runnable).start();
    }
}
